home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC World Komputer 2007 December
/
PCWKCD1207B.iso
/
Blogowanie poza sfera
/
Flock 1.0 beta
/
flock-1.0RC3.en-US.win32.exe
/
flock
/
modules
/
FlockScheduler.jsm
< prev
next >
Wrap
Text File
|
2007-10-18
|
4KB
|
120 lines
// BEGIN FLOCK GPL
//
// Copyright Flock Inc. 2005-2007
// http://flock.com
//
// This file may be used under the terms of of the
// GNU General Public License Version 2 or later (the "GPL"),
// http://www.gnu.org/licenses/gpl.html
//
// Software distributed under the License is distributed on an "AS IS" basis,
// WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
// for the specific language governing rights and limitations under the
// License.
//
// END FLOCK GPL
const CC = Components.classes;
const CI = Components.interfaces;
const CR = Components.results;
var EXPORTED_SYMBOLS = ["FlockScheduler"];
/**
* FlockScheduler.schedule() - A cheap scheduler for javascript tasks.
*
* @param object[] aTimers (in) (optional)
* If provided, any timers created will be stored in this array
* so the caller can cancel them early.
* @param float aSlice (in)
* Maximum timeslice in seconds. 0.5 or less is a good value.
* @param float aPercent (in)
* Percent of wall-clock time that should be spent executing the task.
* For example, 20 = one fifth of the time.
* @param function aTask (in)
* A generator taking a function that evaluates to true if it should
* yield, like this:
*
* function task(should_yield) {
* while (some_condition) {
* do some work...
* if (should_yield()) {
* yield;
* }
* }
* }
*
* @return nothing
*
* NOTE: should_yield() is fairly cheap but in a tight inner loop it might
* make sense to call it every N cycles
*/
var FlockScheduler = {
schedule: function schedule(aTimers, aSlice, aPercent, aTask) {
// convert percent to ratio
var ratio = aPercent / 100.0;
// convert slice to milliseconds
var slice = aSlice * 1000.0;
// A helper to get the current time as milliseconds.
function milliseconds() { return (new Date ()).getTime(); }
var wall_start = milliseconds();
var process_time = 0;
var process_start = 0;
// A function the task can use to decide whether to yield its timeslice.
function should_yield() {
var now = milliseconds();
var so_far = now - process_start;
var wall_time = now - wall_start;
return (so_far >= slice) ||
((wall_time * ratio) < (process_time + so_far));
}
// A generator is (among other things) a function that calls yield().
// To resume execution at the point of suspension by yield(), call the
// generator's .next() method.
// See https://bugzilla.mozilla.org/show_bug.cgi?id=326466
var generator = aTask(should_yield);
var timer = CC["@mozilla.org/timer;1"].createInstance(CI.nsITimer);
var callback = {
notify: function FlockScheduler_callback_notify() {
var wall_time = milliseconds() - wall_start;
if (process_time > (wall_time * ratio)) {
// We've spent more time than we're supposed to; skip this cycle.
return;
}
process_start = milliseconds();
try {
// Resume execution where the function yield()ed.
generator.next();
} catch (err if err instanceof StopIteration) {
// The task is complete; stop timer and destroy it.
timer.cancel();
if (aTimers) {
for (var i = 0; i < aTimers.length; i++) {
if (aTimers[i] === timer) {
aTimers.splice(i, 1);
}
}
}
timer = null;
}
process_time += (milliseconds() - process_start);
}
};
timer.initWithCallback(callback,
Math.round(slice/ratio),
CI.nsITimer.TYPE_REPEATING_SLACK);
if (aTimers) {
aTimers.push(timer);
}
}
};